package com.replication.jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class ReplicationStatementProxy implements Statement{

    private final ReplicationConnectionProxy conn;
    private final StatementOpts stmtOpts = new StatementOpts();
    private Integer resultSetType; 
    private Integer resultSetConcurrency; 
    private Integer resultSetHoldability;
    
    private Statement stmt;
    
    private List<String> batchList = new ArrayList<String>();
    
    public ReplicationStatementProxy(ReplicationConnectionProxy conn){
        this.conn = conn;
    }
    
    public ReplicationStatementProxy(ReplicationConnectionProxy conn,int resultSetType, int resultSetConcurrency){
        this.conn = conn;
        this.resultSetType = resultSetType;
        this.resultSetConcurrency = resultSetConcurrency;
    }
    
    public ReplicationStatementProxy(ReplicationConnectionProxy conn,int resultSetType, int resultSetConcurrency,int resultSetHoldability){
        this.conn = conn;
        this.resultSetType = resultSetType;
        this.resultSetConcurrency = resultSetConcurrency;
        this.resultSetHoldability = resultSetHoldability;
    }
    

    public void addBatch(String sql) throws SQLException {
        batchList.add(sql);
    }

    @Override
    public void cancel() throws SQLException {
        if(stmt==null){
            return;
        }
        stmt.cancel();
    }

    @Override
    public void clearBatch() throws SQLException {
        batchList.clear();
    }

    @Override
    public void clearWarnings() throws SQLException {
        if(stmt==null){
            return;
        }
        stmt.clearWarnings();
    }

    @Override
    public void close() throws SQLException {
        if(stmt==null){
            return;
        }
        stmt.close();
    }

    @Override
    public boolean execute(String sql) throws SQLException {
        stmt = Statements.createStatement(conn, sql,stmtOpts,resultSetType,resultSetConcurrency,resultSetHoldability);
        return stmt.execute(sql);
    }

    @Override
    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
        stmt = Statements.createStatement(conn, sql,stmtOpts,resultSetType,resultSetConcurrency,resultSetHoldability);
        return stmt.execute(sql,autoGeneratedKeys);
    }

    @Override
    public boolean execute(String sql, int[] columnIndexes) throws SQLException {
        stmt = Statements.createStatement(conn, sql,stmtOpts,resultSetType,resultSetConcurrency,resultSetHoldability);
        return stmt.execute(sql,columnIndexes);
    }

    @Override
    public boolean execute(String sql, String[] columnNames) throws SQLException {
        stmt = Statements.createStatement(conn, sql,stmtOpts,resultSetType,resultSetConcurrency,resultSetHoldability);
        return stmt.execute(sql,columnNames);
    }

    @Override
    public int[] executeBatch() throws SQLException {
        stmt = Statements.createStatementOnMaster(conn,stmtOpts,resultSetType,resultSetConcurrency,resultSetHoldability);
        for(String sql:batchList){
            stmt.addBatch(sql);
        }
        return stmt.executeBatch();
    }

    @Override
    public ResultSet executeQuery(String sql) throws SQLException {
        stmt = Statements.createStatement(conn, sql,stmtOpts,resultSetType,resultSetConcurrency,resultSetHoldability);
        return stmt.executeQuery(sql);
    }

    @Override
    public int executeUpdate(String sql) throws SQLException {
        stmt = Statements.createStatementOnMaster(conn,stmtOpts,resultSetType,resultSetConcurrency,resultSetHoldability);
        return stmt.executeUpdate(sql);
    }

    @Override
    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
        stmt = Statements.createStatementOnMaster(conn,stmtOpts,resultSetType,resultSetConcurrency,resultSetHoldability);
        return stmt.executeUpdate(sql,autoGeneratedKeys);
    }

    @Override
    public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
        stmt = Statements.createStatementOnMaster(conn,stmtOpts,resultSetType,resultSetConcurrency,resultSetHoldability);
        return stmt.executeUpdate(sql,columnIndexes);
    }

    @Override
    public int executeUpdate(String sql, String[] columnNames) throws SQLException {
        stmt = Statements.createStatementOnMaster(conn,stmtOpts,resultSetType,resultSetConcurrency,resultSetHoldability);
        return stmt.executeUpdate(sql,columnNames);
    }

    @Override
    public Connection getConnection() throws SQLException {
        return this.conn;
    }

    @Override
    public int getFetchDirection() throws SQLException {
        return stmt.getFetchDirection();
    }

    @Override
    public int getFetchSize() throws SQLException {
        return stmt.getFetchSize();
    }

    @Override
    public ResultSet getGeneratedKeys() throws SQLException {
        return stmt.getGeneratedKeys();
    }

    @Override
    public int getMaxFieldSize() throws SQLException {
        return stmt.getMaxFieldSize();
    }

    @Override
    public int getMaxRows() throws SQLException {
        return stmt.getMaxRows();
    }

    @Override
    public boolean getMoreResults() throws SQLException {
        return stmt.getMoreResults();
    }

    @Override
    public boolean getMoreResults(int current) throws SQLException {
        return stmt.getMoreResults(current);
    }

    @Override
    public int getQueryTimeout() throws SQLException {
        return stmt.getQueryTimeout();
    }

    @Override
    public ResultSet getResultSet() throws SQLException {
        return stmt.getResultSet();
    }

    @Override
    public int getResultSetConcurrency() throws SQLException {
        return stmt.getResultSetConcurrency();
    }

    @Override
    public int getResultSetHoldability() throws SQLException {
        return stmt.getResultSetHoldability();
    }

    @Override
    public int getResultSetType() throws SQLException {
       
        return stmt.getResultSetType();
    }

    @Override
    public int getUpdateCount() throws SQLException {
        return stmt.getUpdateCount();
    }

    @Override
    public SQLWarning getWarnings() throws SQLException {
        return stmt.getWarnings();
    }

    @Override
    public boolean isClosed() throws SQLException {
        return stmt.isClosed();
    }

    @Override
    public boolean isPoolable() throws SQLException {
        return stmt.isPoolable();
    }

    @Override
    public void setCursorName(String name) throws SQLException {
        stmtOpts.setCursorName(name);
    }

    @Override
    public void setEscapeProcessing(boolean enable) throws SQLException {
        stmtOpts.setEscapeProcessing(enable);
    }

    @Override
    public void setFetchDirection(int direction) throws SQLException {
        stmtOpts.setFetchDirection(direction);
    }

    @Override
    public void setFetchSize(int rows) throws SQLException {
        stmtOpts.setFetchSize(rows);
    }

    @Override
    public void setMaxFieldSize(int max) throws SQLException {
        stmtOpts.setMaxFieldSize(max);
    }

    @Override
    public void setMaxRows(int max) throws SQLException {
        stmtOpts.setMaxRows(max);
    }

    @Override
    public void setPoolable(boolean poolable) throws SQLException {
        stmtOpts.setPoolable(poolable);
    }

    @Override
    public void setQueryTimeout(int seconds) throws SQLException {
        stmtOpts.setQueryTimeout(seconds);
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return stmt.isWrapperFor(iface);
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return stmt.unwrap(iface);
    }

}
